package tt.dz.egobus.servicemanager.util;

import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import net.glxn.qrgen.core.AbstractQRCode;
import net.glxn.qrgen.core.image.ImageType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;

import static net.glxn.qrgen.javase.QRCode.from;

/**
 * @author Anson
 * @date 17-3-21
 * @name 二维码生成
 * @since 1.0.2
 */
public final class QRCodeUtils {

    /**
     *
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(QRCodeUtils.class);

    public static final String CHAR_SET = "UTF-8";

    /**
     * @param text 文本内容
     * @author Anson
     * @date 17-3-21
     * @name 创建普通二维码
     * @since 1.0.2
     */
    public static byte[] createQRCode(String text) {
        return createQRCode(text, CHAR_SET, ImageType.PNG, 1000, 1000);
    }

    /**
     * @param text      文本内容
     * @param charset   字体编码类别
     * @param imageType 图片类型
     * @param length    二维码长度
     * @param width     二维码宽度
     * @author Anson
     * @date 17-3-21
     * @name 创建普通二维码
     * @since 1.0.2
     */
    public static byte[] createQRCode(String text, String charset, ImageType imageType, int length, int width) {
        AbstractQRCode qrCode = from(text)
                .withCharset(Charset.forName(charset)
                        .displayName())
                .to(imageType)
                .withSize(length, width);
        ByteArrayOutputStream outputStream = qrCode.stream();
        byte[] bytes = outputStream.toByteArray();
        try {
            outputStream.close();
        } catch (IOException e) {
            LOGGER.error("二维码关闭流异常", e);
        }
        return bytes;
    }

    /**
     * @param text         文本内容
     * @param logoFilePath logo路径
     * @author Anson
     * @date 17-3-21
     * @name
     * @since 1.0.2
     */
    public static byte[] createLogoQRCode(String text, String logoFilePath) {
        return createLogoQRCode(text, logoFilePath, CHAR_SET, ImageType.PNG, 1000, 1000);
    }

    /**
     * @param text         文本内容
     * @param logoFilePath logo路径
     * @param charset      字体编码类别
     * @param imageType    图片类型
     * @param length       二维码长度
     * @param width        二维码宽度
     * @author Anson
     * @date 17-5-24
     * @name 创建当前含有logo的二维码
     * @since 1.0.4
     */
    public static byte[] createLogoQRCode(String text, String logoFilePath, String charset, ImageType imageType, int length, int width) {
        AbstractQRCode qrCode = from(text)
                .withCharset(Charset.forName(charset)
                        .displayName())
                .to(imageType)
                .withSize(length, width)
                .withErrorCorrection(ErrorCorrectionLevel.M);
        ByteArrayOutputStream outputStream = qrCode.stream();
        ByteArrayOutputStream writeOut = new ByteArrayOutputStream();
        byte[] bytes = outputStream.toByteArray();
        int logx = width / 6;
        int logy = length / 6;
        int pointx = (width - logx) / 2;
        int pointy = (length - logy) / 2;
        try {
            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
            BufferedImage bufferedImage = ImageIO.read(inputStream);
            BufferedImage imageBuffered = new BufferedImage(width, length, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics2D = imageBuffered.createGraphics();
            graphics2D.drawImage(bufferedImage, 0, 0, width, length, null);

            Image img = ImageIO.read(new File(logoFilePath));
            graphics2D.drawImage(img, pointx, pointy, logx, logy, null);
            graphics2D.dispose();
            imageBuffered.flush();
            bufferedImage.flush();
            ImageIO.write(imageBuffered, imageType.name(), writeOut);
            bytes = writeOut.toByteArray();
        } catch (IOException e) {
            LOGGER.error("二维码处理流异常", e);
        } finally {
            try {
                if (writeOut != null) {
                    writeOut.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                LOGGER.error("二维码关闭流异常", e);
            }
        }

        return bytes;
    }

}
